package com.zzyl.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.Constants;
import com.zzyl.dto.WxLoginDto;
import com.zzyl.entity.Member;
import com.zzyl.mapper.WeChatLoginMapper;
import com.zzyl.properties.JwtConfigProperties;
import com.zzyl.properties.WeChatConfigProperties;
import com.zzyl.service.WeChatLoginService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author:
 * @Description: TODO
 * @DateTime: 2024/6/16 11:56
 **/
@Service
public class WeChatLoginServiceImpl implements WeChatLoginService {
    @Autowired
    private WeChatLoginMapper weChatLoginMapper;

    @Autowired
    private WeChatConfigProperties weChatConfigProperties;
    @Autowired
    private JwtConfigProperties jwtConfigProperties;

    private static final Map<String,String> map = new HashMap<>();


    @Override
    public LoginVo login(WxLoginDto dto) {
        //1.接收请求、接收数据、转发业务层、响应结果
        String openid = getOpenid(dto.getCode());
        //2.业务层:
        //(1) 根据登录code调用微信登录接口获取用户的openid
        //(2) 需要客户表用来存储微信用户的信息[客户表都有哪些字段?]
        //(3) 如果是新用户[根据openid到客户表中查询]
        Member member = weChatLoginMapper.findByOpenId(openid);
        String nickName = "";
        if(member==null){
            //查不到[生成一个随机的昵称，往表中插入一条数据]
            nickName = "微信用户";
            //往表中插入数据
            member = new Member();
            member.setOpenId(openid);
            member.setName(nickName);
            weChatLoginMapper.insert(member);
        }else{
            //能查到
            //获取表中的昵称
            nickName = member.getName();
        }
        //(4) 根据openid和手机号code获取当前用户的手机号
        String phone = getPhone(dto.getPhoneCode(), dto.getCode(), openid, getAccessToken());
        //(5) 需要将用户的手机号更新到客户表
        Long id = member.getId();
        weChatLoginMapper.updatePhoneById(phone,id);
        //(6) 前面步骤走完后，能够获取到一个客户ID
        //(7) 给客户颁发令牌，将令牌数据返回给前端
        Map<String,Object> claims = new HashMap<>();
        claims.put(Constants.JWT_USERID,id);
        String token = JwtUtil.createJWT(jwtConfigProperties.getBase64EncodedSecretKey(), jwtConfigProperties.getTtl(), claims);
        return LoginVo.builder().token(token).nickName(nickName).build();
    }

    /**
     * 获取openid
     * @param code
     * @return
     */
    private String getOpenid(String code) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("appid",weChatConfigProperties.getAppid());
        paramMap.put("secret",weChatConfigProperties.getSecret());
        paramMap.put("js_code", code);
        paramMap.put("grant_type","authorization_code");
        HttpResponse response = HttpUtil.createRequest(Method.GET, weChatConfigProperties.getLoginUrl())
                .form(paramMap)
                .execute();
        String body = response.body();
        String openid = JSONUtil.parseObj(body).get("openid").toString();
        return openid;
    }

    /**
     * 获取手机号
     * @param phoneCode
     * @param code
     * @param openid
     * @param accessToken
     * @return
     */
    private String getPhone(String phoneCode,String code,String openid,String accessToken){
        //4.发送请求获取手机号
        Map<String,String> phoneMap = new HashMap<>();
        phoneMap.put("code",phoneCode);
        phoneMap.put("openid",openid);
        HttpResponse response = HttpUtil.createRequest(Method.POST, weChatConfigProperties.getPhoneUrl() + accessToken)
                .body(JSONUtil.toJsonStr(phoneMap))
                .execute();
        String body = response.body();
        System.out.println(body);

        String phoneNum = JSONUtil.parseObj(body).getJSONObject("phone_info").get("phoneNumber").toString();
        return phoneNum;
    }

    /**
     * 获取 accessToken
     * @return
     */
    private String getAccessToken(){
        String accessToken = map.get("access_token");
        if(StrUtil.isEmpty(accessToken)){
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("grant_type","client_credential");
            paramMap.put("appid",weChatConfigProperties.getAppid());
            paramMap.put("secret",weChatConfigProperties.getSecret());
            HttpResponse response = HttpUtil.createRequest(Method.GET,weChatConfigProperties.getAccessTokenUrl())
                    .form(paramMap)
                    .execute();
            //json进行传递
            String body = response.body();
            accessToken = JSONUtil.parseObj(body).get("access_token").toString();
            map.put("access_token",accessToken);
        }
        return accessToken;
    }
}
